package com.ken.common.web.async;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;

import javax.annotation.PostConstruct;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;

@ConfigurationProperties(prefix = "async.executor")
@Data
public class AsyncExecurityConfiguration {

    /**
     * 核心线程数
     */
    private Integer coreNum;

    /**
     * 最大线程数
     */
    private Integer maxNum;

    /**
     * 最大空闲时间
     */
    private Integer maxTimeoutSec = 300;

    /**
     * 是否允许核心线程数超时
     */
    private boolean allowCoreThreadTimeOut = false;

    /**
     * 线程名称的前缀
     */
    private String threadNamePrefix = "Ken-Executor-";

    /**
     * 阻塞队列的最大容量
     */
    private Integer queueCapacity = 1000;

    /**
     * 线程拒绝的方式
     */
    private RejectEunm rejectHandler = RejectEunm.CallerRunsPolicy;

    @PostConstruct
    public void init(){
        //获得cpu的核心数量
        int core = Runtime.getRuntime().availableProcessors();

        //配置核心线程数 - cpu核心数 - CPU密集型的应用
        if (coreNum == null || coreNum <= 0) {
            coreNum = core;
        }

        //配置最大线程数 - cpu核心数 * 2 - IO密集型的应用
        if (maxNum == null || maxNum <= 0) {
            maxNum = core * 2;
        }
    }


    public enum RejectEunm {

        //抛出异常的方式
        AbortPolicy(new ThreadPoolExecutor.AbortPolicy()),
        //提交任务的线程自行执行该任务
        CallerRunsPolicy(new ThreadPoolExecutor.CallerRunsPolicy()),
        //线程池会放弃当前等待队列中，最久的任务，当前被拒绝的任何放入队列
        DiscardOldestPolicy(new ThreadPoolExecutor.DiscardOldestPolicy()),
        //直接丢弃当前拒绝的任务
        DiscardPolicy(new ThreadPoolExecutor.DiscardPolicy());

        /**
         * 拒绝策略的处理器
         */
        private RejectedExecutionHandler rejectedExecutionHandler;

        RejectEunm(RejectedExecutionHandler rejectedExecutionHandler) {
            this.rejectedExecutionHandler = rejectedExecutionHandler;
        }

        public RejectedExecutionHandler getRejectedExecutionHandler() {
            return rejectedExecutionHandler;
        }
    }
}
